package com.demo.app.common.auth;

import cn.hutool.http.HttpStatus;
import com.demo.app.exception.PermissionException;
import com.demo.app.util.JwtUtil;
import com.demo.app.util.RedisUtil;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.SignatureException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 权限认证器
 * </p>
 *
 * @author zhangxt
 * @date 2023/11/1
 */
@Component
public class PermissionAuthenticator {

    private final Logger logger = LogManager.getLogger(this.getClass());

    @Autowired
    private RedisUtil redisUtil;

    @Value("${jwt.secretKey}")
    private String secretKey;

    @Value("${jwt.expiration}")
    private String expiration;

    /**
     * <p>
     * 检查token
     * </p>
     *
     * @param token
     * @return {@link Jws<Claims>}
     */
    public Jws<Claims> checkToken(String token) {
        JwtUtil jwtUtil = new JwtUtil(secretKey);
        // 验证token
        Jws<Claims> claims = null;
        try {
            claims = jwtUtil.parseJWT(token);
        } catch (UnsupportedJwtException | SignatureException | IllegalArgumentException e) {
            // 解析异常
            throw new PermissionException("无效的token!", HttpStatus.HTTP_FORBIDDEN);
        } catch (ExpiredJwtException e) {
            // token过期
            throw new PermissionException("登陆超时!", HttpStatus.HTTP_UNAUTHORIZED);
        } catch (MalformedJwtException e) {
            throw new PermissionException("无权访问!", HttpStatus.HTTP_FORBIDDEN);
        } catch (Exception e) {
            logger.error(e);
            throw new PermissionException("服务器异常!", HttpStatus.HTTP_FORBIDDEN);
        }
        return claims;
    }

    /**
     * <p>
     * 注销状态检查
     * </p>
     *
     * @param claims
     */
    public void checkLogout(Jws<Claims> claims) {
        String cacheKey = (String) claims.getBody().get("cacheKey");
        Object o = redisUtil.get(cacheKey);
        if (o == null) {
            throw new PermissionException("该Token已经注销失效!", HttpStatus.HTTP_UNAUTHORIZED);
        }
    }
}
